package com.example.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.config.e0xpayConfig;
import com.example.utils.ESHWeChatUtils;
import com.example.utils.HttpClientUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author ediclot
 * @author prayer
 * @description: 小微支付控制器
 * @date 2019/9/9 9:24
 */
@Controller
@RequestMapping(value = "")
public class e0xpayController {
    private static Logger logger = LoggerFactory.getLogger(e0xpayController.class);

    /**
     * @return : java.lang.String
     * @author ediclot
     * @date 2019/9/9
     * @description: 跳转到主页面
     **/
    @RequestMapping("")
    public String home() {
        return "index";
    }

    /**
     * @param WIDout_trade_no
     * @param WIDsubject
     * @param WIDtotal_fee
     * @param body
     * @param type
     * @param request
     * @param response
     * @param model
     * @return : java.lang.String
     * @author ediclot
     * @date 2019/9/9
     * @description: 支付控制函数
     **/
    @RequestMapping(value = "pay")
    public String payApi(@RequestParam(required = false, value = "WIDout_trade_no") String WIDout_trade_no,
                         @RequestParam(required = false, value = "WIDsubject") String WIDsubject,
                         @RequestParam(required = false, value = "WIDtotal_fee") String WIDtotal_fee,
                         @RequestParam(required = false, value = "body") String body,
                         @RequestParam(required = false, value = "type") String type,
                         HttpServletRequest request,
                         HttpServletResponse response, Model model) {

        if ("JSAPI".equals(type) || type == null) {
            return getOpenid();
        }
        //微信支付
        if ("Native".equals(type)) {
            Map<String, Object> parameters = new TreeMap<String, Object>();
            //
            parameters.put("mch_id", e0xpayConfig.MCH_ID);
            parameters.put("sub_mch_id", e0xpayConfig.SUB_MCH_ID);
            parameters.put("total_fee", 1 * 10);
            parameters.put("out_trade_no", WIDout_trade_no + UUID.randomUUID().toString().substring(0, 5).replace("-", ""));
            parameters.put("subject", WIDsubject);
            parameters.put("attach", "attach");
            parameters.put("pt", e0xpayConfig.PayType.XIAOWEI.name());
            parameters.put("channel", e0xpayConfig.ChannelType.NATIVE.name());
            parameters.put("notify_url", e0xpayConfig.NOTIFY_URL);
            String characterEncoding = "UTF-8";         //指定字符集UTF-8
            parameters.put("sign", ESHWeChatUtils.createSign(characterEncoding, parameters, e0xpayConfig.APP_SECRET));
            try {
                String map2string = ESHWeChatUtils.map2string(parameters);
                String result = HttpClientUtils.send(e0xpayConfig.NATIVE_PAY_API, map2string);
                logger.info("微信下单响应：" + result);
                JSONObject jsonObject = JSONObject.parseObject(result);
                if (jsonObject.getIntValue("status") == 0) {
                    JSONObject dataObject = JSONObject.parseObject(jsonObject.getString("data"));
                    logger.info("微信支付下单成功...");
                    model.addAttribute("siteName", "支付测试");
                    model.addAttribute("title", "支付测试");
                    model.addAttribute("total_fee", new BigDecimal(10).divide(new BigDecimal(100)));
                    model.addAttribute("subject", parameters.get("subject").toString());
                    model.addAttribute("outTradeNo", parameters.get("out_trade_no").toString());
                    model.addAttribute("createDate", new Date());
                    model.addAttribute("model", dataObject.getString("code_url"));
                    return "e0xpayPay";
                } else {
                    logger.info("微信支付下单失败...");
                }
            } catch (Exception e) {
                logger.error("微信支付下单错误 {}", e);
            }
            return null;
        }
        return null;
    }

    /**
     * @return : java.lang.String
     * @author Jesse-liu
     * @date 2019/8/9
     * @description: 支付完成跳转地址
     **/
    @RequestMapping("orderPayResult")
    public String orderPayResult() {
        return "paySuccess";
    }


    /**
     * @param outTradeNo 商户订单号
     * @return : java.util.Map<java.lang.Object,java.lang.Object>
     * @author ediclot
     * @date 2019/9/9
     * @description: 检查微信支付的付款结果 (因为和业务相关所以没做支付后跳转）
     **/
    @RequestMapping("wx_payOrder_state")
    public Map<Object, Object> wx_order_state(String outTradeNo) {
        HashMap<Object, Object> map = null;
        //      map.put("status", "success");
        map.put("backurl", "/orderPayResult");
        return map;
    }

    /**
     * @return : null
     * @author ediclot
     * @date 2019/9/9
     * @description: 获取openid
     **/
    public String getOpenid() {
        Map<String, Object> parameters = new TreeMap<String, Object>();
        parameters.put("mch_id", e0xpayConfig.MCH_ID);
        parameters.put("sub_mch_id", e0xpayConfig.SUB_MCH_ID);
        parameters.put("callback", e0xpayConfig.CALL_BACK);
        String sign = ESHWeChatUtils.createSign("UTF-8", parameters, e0xpayConfig.APP_SECRET);
        parameters.put("sign", sign);
        String map2string = ESHWeChatUtils.map2string(parameters);
        String url = e0xpayConfig.OPENID_API + "?" + map2string;
        return "redirect:" + url;
    }

    /**
     * @return : null
     * @author ediclot
     * @date 2019/9/9
     * @description: 获取openid回调函数
     **/
    @RequestMapping("optionCallBack")
    public String optionCallBack(HttpServletRequest request, HttpServletResponse response, Model model) {
        logger.info(request.getParameter("openid"));
        String openid = "";
        if (request.getParameter("openid") != null && request.getParameter("openid") != "") {
            openid = request.getParameter("openid");
        }
        Map<String, Object> parameters = new TreeMap<String, Object>();
        parameters.put("mch_id", e0xpayConfig.MCH_ID);
        parameters.put("sub_mch_id", e0xpayConfig.SUB_MCH_ID);
        parameters.put("openid", openid);
        parameters.put("total_fee", 1 * 10);
        parameters.put("out_trade_no", UUID.randomUUID().toString().substring(0, 10).replace("-", ""));
        parameters.put("subject", "小微支付JSAPI测试");
        parameters.put("attach", "附属信息");
        parameters.put("channel", e0xpayConfig.ChannelType.JSAPI.name());
        parameters.put("pt", e0xpayConfig.PayType.XIAOWEI.name());
        parameters.put("notify_url", e0xpayConfig.NOTIFY_URL);
        String characterEncoding = "UTF-8";         //指定字符集UTF-8
        parameters.put("sign", ESHWeChatUtils.createSign(characterEncoding, parameters, e0xpayConfig.APP_SECRET));
        try {
            //把map转string  发送的信息
            String map2string = ESHWeChatUtils.map2string(parameters);
            String result = HttpClientUtils.send(e0xpayConfig.JSAPI_PAY_API, map2string);
            logger.info("微信下单响应：" + result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getIntValue("status") == 0) {
                JSONObject dataObject = jsonObject.getJSONObject("data");
                String payinfo = dataObject.getString("pay_info");
                JSONObject payInfo = JSON.parseObject(payinfo);
                logger.info("微信支付下单成功...");
                model.addAttribute("jsapi_app_id", payInfo.getString("appId"));
                model.addAttribute("jsapi_timeStamp", payInfo.getString("timeStamp"));
                model.addAttribute("jsapi_nonceStr", payInfo.getString("nonceStr"));
                model.addAttribute("jsapi_package", payInfo.getString("package"));
                model.addAttribute("jsapi_signType", payInfo.getString("signType"));
                model.addAttribute("jsapi_paySign", payInfo.getString("paySign"));
                return "e0xpayPayWap";
            } else {
                logger.error("微信支付下单失败 {}", jsonObject.toJSONString());
            }
        } catch (Exception e) {
            logger.error("微信支付错误 {}", e);
        }
        return null;
    }

    /**
     * @return : null
     * @author ediclot
     * @date 2019/9/9
     * @description:
     **/
    @RequestMapping("toAPIInterface")
    public String toRefund() {
        return "APIInterface";
    }

    /**
     * @param out_trade_no 用户自定义订单编号
     * @param order_sn     平台订单号
     * @param refund_fee   退款金额
     * @param model
     * @return : java.lang.String
     * @author ediclot
     * @date 2019/9/9
     * @description: 退款接口
     **/
    @ResponseBody
    @RequestMapping("refund")
    public String refund(String out_trade_no, String refund_fee, Model model) {

        Map<String, Object> parameters = new TreeMap<String, Object>();
        parameters.put("mch_id", e0xpayConfig.MCH_ID);
        parameters.put("sub_mch_id", e0xpayConfig.SUB_MCH_ID);
        parameters.put("refund_fee", refund_fee);
        if (out_trade_no != null && out_trade_no != "") {
            parameters.put("out_trade_no", out_trade_no);
        }
        String characterEncoding = "UTF-8";         //指定字符集UTF-8
        parameters.put("sign", ESHWeChatUtils.createSign(characterEncoding, parameters, e0xpayConfig.APP_SECRET));
        //把map转string  发送的信息
        String map2string = ESHWeChatUtils.map2string(parameters);
        String result = HttpClientUtils.send(e0xpayConfig.REFUND_API, map2string);
        logger.info("微信退款响应：" + result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getIntValue("status") == 0) {
            JSONObject dataObject = JSONObject.parseObject(jsonObject.getString("data"));
            logger.info("微信退款成功...");
            model.addAttribute("status_text", "微信退款成功");
            return dataObject.toJSONString();
        } else {
            model.addAttribute("status_text", jsonObject.getString("message"));
        }
        model.addAttribute("refund_fee", refund_fee);
        model.addAttribute("out_trade_no", out_trade_no);
        return "refund";
    }

    /**
     * @param out_trade_no 用户自定义订单编号
     * @param order_sn     平台订单号
     * @param refund_fee   退款金额
     * @param model
     * @return : java.lang.String
     * @author ediclot
     * @date 2019/9/9
     * @description:查询接口
     **/
    @ResponseBody
    @RequestMapping("query")
    public String query(String out_trade_no, String type, Model model) {
        Map<String, Object> parameters = new TreeMap<String, Object>();
        parameters.put("mch_id", e0xpayConfig.MCH_ID);
        if (out_trade_no != null && out_trade_no != "") {
            parameters.put("out_trade_no", out_trade_no);
        }
        String characterEncoding = "UTF-8";         //指定字符集UTF-8
        parameters.put("sign", ESHWeChatUtils.createSign(characterEncoding, parameters, e0xpayConfig.APP_SECRET));
        //把map转string  发送的信息
        String map2string = ESHWeChatUtils.map2string(parameters);
        String result = HttpClientUtils.send(e0xpayConfig.QUERY_API, map2string);
        logger.info("微信订单交易状态响应：" + result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getIntValue("status") == 0) {
            JSONObject dataObject = JSONObject.parseObject(jsonObject.getString("data"));
            logger.info("微信订单查询成功...");
            if (dataObject.getIntValue("status") == 1 && "json".equals(type)) {
                return "{\"status\":\"success\"}";
            }
            model.addAttribute("status_text", dataObject.getString("message"));
        } else {
            model.addAttribute("status_text", jsonObject.getString("message"));
        }
        model.addAttribute("out_trade_no", out_trade_no);
        return "{\"status\":\"false\"}";
    }
}
